package org.example.ai04.service;

import com.google.gson.Gson;
import org.example.ai04.dto.ResumeData;
import org.example.ai04.dto.ResumeData.ResumeAnalysis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 简历处理服务类
 * 负责简历数据的格式转换、JSON序列化/反序列化以及聊天消息处理
 * 是连接简历解析与前端展示的桥梁，处理各种数据格式转换和预处理操作
 */
@Service
public class ResumeProcessingService {

    // 日志记录器，用于记录服务操作和错误信息
    private static final Logger logger = LoggerFactory.getLogger(ResumeProcessingService.class);
    
    // Gson实例，用于JSON序列化和反序列化操作
    private final Gson gson = new Gson();

    // 注入简历分析服务，用于对简历进行分析评分
    @Autowired
    private ResumeAnalysisService resumeAnalysisService;

    /**
     * 将Map格式的简历数据转换为结构化的ResumeData对象
     * 从原始解析结果中提取各种字段的值并设置到ResumeData对象中，确保数据格式统一和结构化
     * 
     * @param resumeDataMap 从AI模型解析得到的Map格式简历数据
     * @return 结构化的ResumeData对象，包含完整的简历信息
     */
    public ResumeData convertMapToResumeData(Map<String, Object> resumeDataMap) {
        // 第一步：创建新的ResumeData对象用于存储结构化的简历数据
        ResumeData resumeData = new ResumeData();
        
        // 第二步：设置基本信息字段
        resumeData.setName(getStringValue(resumeDataMap, "name"));           // 设置姓名
        resumeData.setEmail(getStringValue(resumeDataMap, "email"));         // 设置邮箱
        resumeData.setPhone(getStringValue(resumeDataMap, "phone"));         // 设置电话
        resumeData.setAddress(getStringValue(resumeDataMap, "address"));     // 设置地址
        resumeData.setAge(getStringValue(resumeDataMap, "age"));             // 设置年龄
        resumeData.setBirthDate(getStringValue(resumeDataMap, "birthDate")); // 设置出生日期
        resumeData.setNationality(getStringValue(resumeDataMap, "nationality")); // 设置国籍
        resumeData.setLinkedin(getStringValue(resumeDataMap, "linkedin"));   // 设置LinkedIn个人主页
        resumeData.setGithub(getStringValue(resumeDataMap, "github"));       // 设置GitHub个人主页
        resumeData.setWebsite(getStringValue(resumeDataMap, "website"));     // 设置个人网站
        resumeData.setSummary(getStringValue(resumeDataMap, "summary"));     // 设置个人简介
        resumeData.setObjective(getStringValue(resumeDataMap, "objective")); // 设置职业目标
        
        // 第三步：处理列表类型数据（字符串列表）
        resumeData.setSkills(getListValue(resumeDataMap, "skills"));           // 设置技能列表
        resumeData.setLanguages(getListValue(resumeDataMap, "languages"));     // 设置语言能力列表
        resumeData.setCertifications(getListValue(resumeDataMap, "certifications")); // 设置证书列表
        resumeData.setProjects(getListValue(resumeDataMap, "projects"));       // 设置项目经历列表
        
        // 第四步：处理教育背景信息，转换为Education对象列表
        resumeData.setEducation(processEducationData(resumeDataMap.get("education")));
        
        // 第五步：处理工作经历信息，转换为WorkExperience对象列表
        resumeData.setWorkExperience(processWorkExperienceData(resumeDataMap.get("workExperience")));
        
        // 第六步：返回填充完毕的结构化ResumeData对象
        return resumeData;
    }

    /**
     * 分析简历并生成评分和建议
     * 委托给ResumeAnalysisService执行具体的分析逻辑，对简历内容进行智能评估
     * 
     * @param resumeData 要分析的结构化简历数据
     * @param aiModel 要使用的AI模型名称
     * @return 包含评分和建议的ResumeAnalysis对象
     * @throws Exception 当分析过程中发生错误时抛出（如API调用失败、模型处理异常等）
     */
    public ResumeData.ResumeAnalysis analyzeResume(ResumeData resumeData, String aiModel) throws Exception {
        // 调用简历分析服务进行具体的简历分析
        return resumeAnalysisService.analyzeResume(resumeData, aiModel);
    }

    /**
     * 将ResumeData对象转换为JSON字符串
     * 用于前端JavaScript处理或存储，便于数据传输和展示
     * 
     * @param resumeData 要序列化的ResumeData对象
     * @return JSON格式的字符串，包含完整的简历信息
     */
    public String convertToJson(ResumeData resumeData) {
        // 使用Gson将ResumeData对象序列化为JSON字符串
        return gson.toJson(resumeData);
    }

    /**
     * 将JSON字符串解析为ResumeData对象
     * 用于从前端接收简历数据或从存储中读取，实现数据的反序列化
     * 
     * @param resumeDataJson 包含简历数据的JSON字符串
     * @return 解析得到的ResumeData对象
     */
    public ResumeData parseResumeDataFromJson(String resumeDataJson) {
        // 使用Gson将JSON字符串反序列化为ResumeData对象
        return gson.fromJson(resumeDataJson, ResumeData.class);
    }

    /**
     * 解析聊天历史记录的JSON字符串
     * 用于从前端接收聊天历史数据，支持聊天会话的恢复和展示
     * 
     * @param chatHistory 聊天历史记录的JSON字符串
     * @return 解析得到的ChatMessage对象列表，如果输入为空则返回空列表
     */
    public List<ResumeData.ChatMessage> parseChatHistory(String chatHistory) {
        // 检查聊天历史是否为空
        if (chatHistory == null || chatHistory.trim().isEmpty()) {
            // 为空时返回空列表
            return new ArrayList<>();
        } else {
            try {
                // 使用TypeToken获取泛型列表的类型
                java.lang.reflect.Type listType = new com.google.gson.reflect.TypeToken<ArrayList<ResumeData.ChatMessage>>(){}.getType();
                // 将JSON字符串反序列化为ChatMessage对象列表
                return gson.fromJson(chatHistory, listType);
            } catch (Exception e) {
                // 解析过程中发生异常时记录错误日志并返回空列表
                logger.error("解析聊天历史记录时发生异常", e);
                return new ArrayList<>();
            }
        }
    }

    /**
     * 创建欢迎消息，用于初始化聊天界面
     * 生成一个由AI助手发送的欢迎语，提升用户交互体验
     * 
     * @return 包含欢迎消息的ChatMessage列表
     */
    public List<ResumeData.ChatMessage> createWelcomeChat() {
        // 创建聊天消息列表
        List<ResumeData.ChatMessage> chatMessages = new ArrayList<>();
        // 创建欢迎消息对象
        ResumeData.ChatMessage welcomeMessage = new ResumeData.ChatMessage();
        // 设置欢迎消息内容
        welcomeMessage.setContent("您好！我是AI简历助手，已为您解析完成简历。请问有什么可以帮助您的？");
        // 设置消息角色为AI助手
        welcomeMessage.setRole("assistant");
        // 设置消息时间戳为当前时间
        welcomeMessage.setTimestamp(new Date().toString());
        // 将欢迎消息添加到列表中
        chatMessages.add(welcomeMessage);
        // 返回包含欢迎消息的列表
        return chatMessages;
    }



    /**
     * 从Map中安全地获取字符串类型的值
     * 如果值不存在或为null，返回null，避免空指针异常
     * 
     * @param map 要获取值的Map
     * @param key 要获取的键
     * @return 字符串类型的值，如果不存在则返回null
     */
    private String getStringValue(Map<String, Object> map, String key) {
        // 从Map中获取指定键的值
        Object value = map.get(key);
        // 非空时转换为字符串，否则返回null
        return value != null ? value.toString() : null;
    }

    /**
     * 从Map中安全地获取列表类型的值
     * 如果值不存在或不是List类型，返回空列表，确保调用方始终获得一个可用的列表对象
     * 
     * @param map 要获取值的Map
     * @param key 要获取的键
     * @return List<String>类型的值，如果不存在或类型不匹配则返回空列表
     */
    @SuppressWarnings("unchecked")
    private List<String> getListValue(Map<String, Object> map, String key) {
        // 从Map中获取指定键的值
        Object value = map.get(key);
        // 检查值是否为List类型
        if (value instanceof List) {
            // 类型转换并返回
            return (List<String>) value;
        }
        // 不是List类型时返回空列表
        return new ArrayList<>();
    }

    /**
     * 处理教育背景数据，将原始对象转换为Education对象列表
     * 进行类型检查并逐个转换列表中的每个教育经历项，确保数据格式统一和结构化
     * 
     * @param educationObj 原始的教育背景数据对象
     * @return 转换后的Education对象列表，如果输入无效则返回空列表
     */
    private List<ResumeData.Education> processEducationData(Object educationObj) {
        // 第一步：创建用于存储教育经历的列表
        List<ResumeData.Education> educationList = new ArrayList<>();
        // 第二步：检查输入对象是否为List类型
        if (educationObj instanceof List) {
            // 类型转换为List
            List<?> educationMaps = (List<?>) educationObj;
            // 第三步：遍历列表中的每个教育经历项
            for (Object item : educationMaps) {
                // 检查每个项是否为Map类型
                if (item instanceof Map) {
                    try {
                        // 类型转换为Map
                        Map<?, ?> eduMap = (Map<?, ?>) item;
                        // 创建新的Education对象
                        ResumeData.Education education = new ResumeData.Education();
                        // 设置教育经历的各个字段
                        education.setDegree(getStringValue((Map<String, Object>) eduMap, "degree"));           // 学位
                        education.setSchool(getStringValue((Map<String, Object>) eduMap, "school"));           // 学校
                        education.setMajor(getStringValue((Map<String, Object>) eduMap, "major"));             // 专业
                        education.setGraduationYear(getStringValue((Map<String, Object>) eduMap, "graduationYear")); // 毕业年份
                        education.setGpa(getStringValue((Map<String, Object>) eduMap, "gpa"));                 // GPA
                        education.setStartDate(getStringValue((Map<String, Object>) eduMap, "startDate"));     // 开始日期
                        education.setEndDate(getStringValue((Map<String, Object>) eduMap, "endDate"));         // 结束日期
                        education.setDescription(getStringValue((Map<String, Object>) eduMap, "description")); // 描述
                        // 将填充好的Education对象添加到列表中
                        educationList.add(education);
                    } catch (ClassCastException e) {
                        // 类型转换异常时记录警告日志并跳过该项
                        logger.warn("转换教育经历数据时发生类型转换异常，跳过该项", e);
                    }
                }
            }
        }
        // 第四步：返回处理后的教育经历列表
        return educationList;
    }

    /**
     * 处理工作经历数据，将原始对象转换为WorkExperience对象列表
     * 进行类型检查并逐个转换列表中的每个工作经历项，确保数据格式统一和结构化
     * 
     * @param workExperienceObj 原始的工作经历数据对象
     * @return 转换后的WorkExperience对象列表，如果输入无效则返回空列表
     */
    private List<ResumeData.WorkExperience> processWorkExperienceData(Object workExperienceObj) {
        // 第一步：创建用于存储工作经历的列表
        List<ResumeData.WorkExperience> workExperienceList = new ArrayList<>();
        // 第二步：检查输入对象是否为List类型
        if (workExperienceObj instanceof List) {
            // 类型转换为List
            List<?> workExperienceMaps = (List<?>) workExperienceObj;
            // 第三步：遍历列表中的每个工作经历项
            for (Object item : workExperienceMaps) {
                // 检查每个项是否为Map类型
                if (item instanceof Map) {
                    try {
                        // 类型转换为Map
                        Map<?, ?> workMap = (Map<?, ?>) item;
                        // 创建新的WorkExperience对象
                        ResumeData.WorkExperience workExperience = new ResumeData.WorkExperience();
                        // 设置工作经历的各个字段
                        workExperience.setCompany(getStringValue((Map<String, Object>) workMap, "company"));       // 公司名称
                        workExperience.setPosition(getStringValue((Map<String, Object>) workMap, "position"));     // 职位
                        workExperience.setStartDate(getStringValue((Map<String, Object>) workMap, "startDate"));   // 开始日期
                        workExperience.setEndDate(getStringValue((Map<String, Object>) workMap, "endDate"));       // 结束日期
                        workExperience.setDescription(getStringValue((Map<String, Object>) workMap, "description")); // 工作描述
                        workExperience.setLocation(getStringValue((Map<String, Object>) workMap, "location"));     // 工作地点
                        workExperience.setDepartment(getStringValue((Map<String, Object>) workMap, "department")); // 部门
                        
                        // 处理成就列表（嵌套列表处理）
                        Object achievementsObj = workMap.get("achievements");
                        if (achievementsObj instanceof List) {
                            // 如果是List类型，直接设置
                            workExperience.setAchievements((List<String>) achievementsObj);
                        } else {
                            // 否则设置为空列表
                            workExperience.setAchievements(new ArrayList<>());
                        }
                        
                        // 将填充好的WorkExperience对象添加到列表中
                        workExperienceList.add(workExperience);
                    } catch (ClassCastException e) {
                        // 类型转换异常时记录警告日志并跳过该项
                        logger.warn("转换工作经历数据时发生类型转换异常，跳过该项", e);
                    }
                }
            }
        }
        // 第四步：返回处理后的工作经历列表
        return workExperienceList;
    }
}